package com.cn.haspital.config.interceptor;

import cn.dev33.satoken.exception.NotRoleException;
import com.cn.hospital.exception.FourZeroFourException;
import com.cn.hospital.exception.TokenException;
import com.cn.hospital.utils.AppJwtUtil;
import com.cn.hospital.utils.RedisUtils;
import io.jsonwebtoken.Claims;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局拦截器
 */


@Log4j2
public class WholeTokenInterceptor implements HandlerInterceptor {

    @Autowired
    RedisUtils redisUtils;

    /**
     * 在请求处理之前进行调用（Controller方法调用之前）
     *
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        setCharacterEncoding(response);

        String url = request.getServletPath();
        log.info("preHandle running...  url : {}", url);
        if ("/login".equals(url)) {
            return true;
        }

        isStatus(response.getStatus());

        return disposeToken();
    }

    /**
     * token验证
     *
     * @return
     * @throws TokenException
     */
    public Boolean disposeToken() throws TokenException {
        String tokenValue = getTokenValue("token");
        String SaTokenValue = getTokenValue("sa-token");
        if (StringUtils.isEmpty(tokenValue) && StringUtils.isEmpty(SaTokenValue)) {
            // 抛出异常 单独抓取 返回用户token过期,或者不存在
            throw new TokenException();
        } else {
            return jwtTokenDispose(tokenValue);
        }
    }

    /**
     * jwt Token 验证
     * @param tokenValue
     * @return
     */


    public Boolean jwtTokenDispose(String tokenValue) {
        Claims claims = AppJwtUtil.getClaimsBody(tokenValue);
        int result = AppJwtUtil.verifyToken(claims);
        if (result == 0 || result == -1) {
            Integer userId = (Integer) claims.get("id");
            log.info("当前用户id userId:{}", userId);
            return true;
        }
        return false;
    }

    /**
     * token value判断
     *
     * @param key
     * @return
     */
    public String getTokenValue(String key) {
        String token = (String) this.redisUtils.get(key);
        if ("null".equals(token) || "".equals(token)) token = null;
        if (StringUtils.isEmpty(token)) token = null;
        return token;
    }

    /**
     * 请求码判断
     *
     * @param status
     */
    @SneakyThrows
    public void isStatus(int status) {
        if (status == 404) {
            throw new FourZeroFourException();
        }
        if (status == 403) {
            throw new NotRoleException("");
        }
    }

    /**
     * 乱码处理
     *
     * @param response
     */
    public void setCharacterEncoding(HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
    }

    /**
     * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        setCharacterEncoding(response);
    }

    /**
     * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        setCharacterEncoding(response);
    }

    public static void main(String[] args) {
        String s = null;
        System.out.println(StringUtils.isEmpty(s));
    }
}

